package com.lanxin.judge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lanxin.bx.entity.BxInformal;
import com.lanxin.bx.service.IBxInformalService;
import com.lanxin.hr.entity.ZzAccount;
import com.lanxin.hr.entity.ZzEmployee;
import com.lanxin.hr.service.IZzEmployeeService;
import com.lanxin.judge.Vo.ApplyVo;
import com.lanxin.judge.Vo.ApprovalVo;
import com.lanxin.judge.Vo.NodeVo;
import com.lanxin.judge.entity.LcApproval;
import com.lanxin.judge.entity.LcFlow;
import com.lanxin.judge.entity.LcNode;
import com.lanxin.judge.mapper.LcApprovalMapper;
import com.lanxin.judge.service.ILcApprovalService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lanxin.judge.service.ILcFlowService;
import com.lanxin.judge.service.ILcNodeService;
import com.lanxin.zc.entity.ZcAssetmoveapply;
import com.lanxin.zc.entity.ZcAssetpurchaseapply;
import com.lanxin.zc.service.IZcAssetmoveapplyService;
import com.lanxin.zc.service.IZcAssetpurchaseapplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author author
 * @since 2025-08-11
 */
@Service
public class LcApprovalServiceImpl extends ServiceImpl<LcApprovalMapper, LcApproval> implements ILcApprovalService {
    @Autowired
    private IZzEmployeeService employeeService;

    @Autowired
    private LcApprovalMapper approvalMapper;

    @Autowired
    private IBxInformalService bxInformalService;

    @Autowired
    private ILcNodeService nodeService;

    @Autowired
    private IZcAssetpurchaseapplyService assetpurchaseapplyService;

    @Autowired
    private IZcAssetmoveapplyService assetmoveapplyService;

    @Autowired
    private ILcFlowService flowService;

    //获取我需要审批的单据
    @Override
    public List<ApplyVo> getMyApprovals(ZzAccount account) {
        if(account == null){
            return null;
        }
        Integer eid = account.getAid();//员工id
        ZzEmployee employee = employeeService.getById(eid);
        List<ApplyVo> myApprovals = new ArrayList<>();//存放我的待审批单据
        //获取所有的待审批单据
        List<LcApproval> approvals = approvalMapper.selectList(new QueryWrapper<LcApproval>().eq("status", "O"));
        if(approvals == null){
            return null;
        }
        for (LcApproval approval : approvals) {
            /*获取我需要审批的单据-begin*/

            //根据流程id获取所有的审批节点
            List<NodeVo> nodeVos = nodeService.listNode(approval.getFlowid());

            NodeVo currentNode = null;
            for (NodeVo nodeVo : nodeVos) {
                //如果按部门审批，判断我是不是和申请人同一部门的经理
                if(nodeVo.getIsByDept().equals("Y")){
                    if(employee.getDeptid().equals(approval.getDeptid())&&employee.getJobid()==3){
                        currentNode=nodeVo;
                    }
                } else{
                    //如果不按部门审批
                    if(nodeVo.getDeptid().equals(employee.getDeptid())&&nodeVo.getJobid().equals(employee.getJobid())){
                        currentNode=nodeVo;
                    }
                }
                if(currentNode!=null){
                    break;
                }
            }

            if(currentNode==null){
                continue;
            }else {
                //如果在该申请单的流程节点中查询到我的信息则进行下一步
                ApplyVo applyVo = new ApplyVo();
                //判断当前节点是不是待审批单据需要的审批节点
                if(currentNode.getOid()!=approval.getNodeid()){
                    //如果不是当前审批需要的节点则提前结束循环
                    break;
                }else {
                    //如果是当前审批需要的节点则进行下一步判断
                    //如果我是头结点则正常显示
                    if(currentNode.getPrenodeid()==null){
                        applyVo.setOid(approval.getOid());
                        applyVo.setDocType(approval.getDoctype());
                        applyVo.setDocNo(approval.getDocNo());
                        applyVo.setProposer(approval.getProposer());
                        applyVo.setDeptId(approval.getDeptid());
                        applyVo.setFlowId(approval.getFlowid());
                        applyVo.setStatus(approval.getStatus());
                        applyVo.setSubmitDate(approval.getSubmitDate());
                        myApprovals.add(applyVo);
                    }else {
                        //如果我不是头节点则检查我前面的节点是否已经审批完成
                        //获取我的前项节点
                        LcNode preNode = nodeService.getById(currentNode.getPrenodeid());
                        //根据订单号拿到该订单的所有审批记录
                        List<LcApproval> approvals2 = new ArrayList<>();
                        approvals2 = approvalMapper.selectList(new QueryWrapper<LcApproval>().eq("docNo",approval.getDocNo()));
                        //通过前项节点找到前项节点的审批记录
                        for (LcApproval item:approvals2){
                            //如果我的前项节点审批通过则显示我要审批的节点
                            if(item.getStatus().equals("Y")&&item.getNodeid().equals(preNode.getOid())){
                                applyVo.setOid(approval.getOid());
                                applyVo.setDocType(approval.getDoctype());
                                applyVo.setDocNo(approval.getDocNo());
                                applyVo.setProposer(approval.getProposer());
                                applyVo.setDeptId(approval.getDeptid());
                                applyVo.setFlowId(approval.getFlowid());
                                applyVo.setStatus(approval.getStatus());
                                applyVo.setSubmitDate(approval.getSubmitDate());
                                myApprovals.add(applyVo);
                            }
                        }
                    }
                }
            }
            /*获取我需要审批的单据-end*/
        }
        //查询申请人姓名
        for (ApplyVo applyVo : myApprovals) {
            String empName = employeeService.getEmpVoByEid(applyVo.getProposer()).getEmpName();
            applyVo.setProposerName(empName);
        }
        return myApprovals;
    }


    //审批申请
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void doApproval(ZzEmployee employee,ApplyVo applyVo,Integer oid, String status, String opinion) {
        try {
            Integer flowId = applyVo.getFlowId();
            //生成审批记录
            //获取审批节点
            List<NodeVo> nodeVos = nodeService.listNode(applyVo.getFlowId());
            //当前节点
            Integer nodeId=-1;
            //下一个节点
            Integer nextNodeId=-1;
            //找到当前是哪个审批节点
            int i=0;
            for (NodeVo nodeVo : nodeVos) {
                //放行董事，总经理，超级管理员,这三者统一为超级管理员的身份审批
                if(employee.getOid()==1){
                    nodeId = 5;
                    break;
                }
                //按部门审批
                if("Y".equals(nodeVo.getIsByDept())){
                    //判断我是不是和申请人同一个部门的经理
                    if(employee.getJobid()==3&&applyVo.getDeptId().equals(employee.getDeptid())){
                        nodeId=nodeVo.getOid();
                        //如果有下一个节点则获取下一个节点
                        if(i+1<nodeVos.size()){
                            nextNodeId=nodeVos.get(i+1).getOid();
                        }
                    }
                }
                //不按部门审批
                else if (nodeVo.getDeptid().equals(employee.getDeptid())&&nodeVo.getJobid().equals(employee.getJobid())) {
                    nodeId=nodeVo.getOid();
                    //如果有下一个节点则获取下一个节点
                    if(i+1<nodeVos.size()){
                        nextNodeId=nodeVos.get(i+1).getOid();
                    }
                }
                i++;
            }
            //修改目前审批的申请的状态，添加审批人id，审批意见，审批时间，标志着当前节点审批完成
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("approvalId",employee.getOid());
            map.put("status",status);
            map.put("opinion",opinion);
            map.put("approvalDate",LocalDateTime.now());
            map.put("oid",applyVo.getOid());
            int row = approvalMapper.doApproval(map);
            if(row<1){
                throw new RuntimeException("审批失败");
            }
            //如果当前节点审批通过并且还有下一个节点则生成下一个节点的的待审批记录
            if("Y".equals(status)&&nextNodeId!=-1){
                LcApproval approval = new LcApproval();
                approval.setDoctype(applyVo.getDocType());
                approval.setDocNo(applyVo.getDocNo());
                approval.setDocid(applyVo.getOid());
                approval.setProposer(applyVo.getProposer());
                approval.setDeptid(applyVo.getDeptId());
                approval.setFlowid(applyVo.getFlowId());
                approval.setNodeid(nextNodeId);
                approval.setStatus("O");
                approval.setSubmitDate(applyVo.getSubmitDate());
                approvalMapper.insert(approval);
            }
//---------------------------------------------------------------------------------------------------------------------
            //报销申请
            //根据类型和申请单id获取审批记录
            List<ApprovalVo> approvals = getApprovalByDocNo(applyVo.getDocNo());
            //修改报销申请状态
            if(applyVo.getDocType().equals("BXD")){
                //董事，总经理，超级管理员可以无视其他节点决定审批的通过与否
                if(employee.getOid()==1||employee.getJobid()==1||employee.getJobid()==2){
                    bxInformalService.updateBxStatus(oid,status);
                    return;
                }
                //审批通过的标识
                boolean isPass = true;
                for (LcApproval approval1 : approvals) {
                    //只要有一个节点不通过，审批就失败
                    if("N".equals(approval1.getStatus())){
                        bxInformalService.updateBxStatus(oid,"N");
                        isPass = false;
                        break;
                    }
                }
                //如果所有节点都通过则修改申请状态为通过
                if(approvals.size()==nodeVos.size()&&isPass){
                    bxInformalService.updateBxStatus(oid,"Y");
                }
            }
            //------------------------------------------------------------------
            //资产购买申请
            if(applyVo.getDocType().equals("GMD")){
                //董事，总经理，超级管理员可以无视其他节点决定审批的通过与否
                if(employee.getOid()==1||employee.getJobid()==1||employee.getJobid()==2){
                    assetpurchaseapplyService.updateAssetPurchaseStatus(oid,status);
                    return;
                }
                //审批通过的标识
                boolean isPass = true;
                for (LcApproval approval1 : approvals) {
                    //只要有一个节点不通过，审批就失败
                    if("N".equals(approval1.getStatus())){
                        assetpurchaseapplyService.updateAssetPurchaseStatus(oid,"N");
                        isPass = false;
                        break;
                    }
                }
                //如果所有节点都通过则修改申请状态为通过
                if(approvals.size()==nodeVos.size()&&isPass){
                    assetpurchaseapplyService.updateAssetPurchaseStatus(oid,"Y");
                }
            }
            //-----------------------------------------------------------------------------------
            //资产移动申请
            if(applyVo.getDocType().equals("YDD")){
                //董事，总经理，超级管理员可以无视其他节点决定审批的通过与否
                if(employee.getOid()==1||employee.getJobid()==1||employee.getJobid()==2){
                    assetmoveapplyService.updateAssetMoveStatus(oid,status);
                    return;
                }
                //审批通过的标识
                boolean isPass = true;
                for (LcApproval approval1 : approvals) {
                    //只要有一个节点不通过，审批就失败
                    if("N".equals(approval1.getStatus())){
                        //修改资产移动申请的审批状态
                        assetmoveapplyService.updateAssetMoveStatus(oid,"N");
                        isPass = false;
                        break;
                    }
                }
                //如果所有节点都通过则修改申请状态为通过
                if(approvals.size()==nodeVos.size()&&isPass){
                    //修改资产移动申请的审批状态
                    assetmoveapplyService.updateAssetMoveStatus(oid,"Y");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("审批失败");
        }
    }

    //根据申请单号查询申请审批时间
    @Override
    public String getApprovalDateByDocNo(String docNo) {
        return approvalMapper.getApprovalDateByDocNo(docNo);
    }


    //获取我的所有申请单
    @Override
    public List<ApplyVo> listMyDoc(ZzEmployee employee) {
        List<ApplyVo> docs = new ArrayList<>();
        List<LcApproval> approvals = approvalMapper.selectList(new QueryWrapper<LcApproval>().eq("proposer",employee.getOid()));
        for (LcApproval approval : approvals) {
            ApplyVo applyVo = new ApplyVo();
            applyVo.setDocNo(approval.getDocNo());
            applyVo.setDocType(approval.getDoctype());
            applyVo.setSubmitDate(approval.getSubmitDate());
            if(approval.getApprovalDate()!=null){
                applyVo.setApproveDate(approval.getApprovalDate());
            }
            applyVo.setStatus(approval.getStatus());
            docs.add(applyVo);
        }
        return docs;
    }

    //根据申请单编号获取审批记录vo
    @Override
    public List<ApprovalVo> getApprovalByDocNo(String docNo) {
        List<ApprovalVo> approvalVos = approvalMapper.getApprovalByDocNo(docNo);
        for (ApprovalVo approvalVo : approvalVos) {
            LcNode node =  nodeService.getById(approvalVo.getNodeid());
            approvalVo.setNodeName(node.getName());
        }
        return approvalVos;
    }

}
